

#include "sector_io.h"
#include <stdio.h>  /* printf() */
#include <string.h> /* memset() */
//#include <bios.h>   /* _DISK_... */



#define	DRV_NAME	"sectorio"
#define DRV_FILENAME	"sectorio.sys"

#define SECTOR_IO_DEVICE       0x8000

#define IOCTL_SECTOR_READ		CTL_CODE(SECTOR_IO_DEVICE, 0x800, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_SECTOR_WRITE		CTL_CODE(SECTOR_IO_DEVICE, 0x801, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_GET_SECTOR_SIZE	CTL_CODE(SECTOR_IO_DEVICE, 0x802, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)

void dumpIt(void *, int );
unsigned long getMFT(unsigned long,int);
unsigned long long getNextVCN(unsigned int*,unsigned int,unsigned long long*);
unsigned int locateIndex(unsigned long ,int,int);
unsigned long long lookUpFolderDirectory(char*,unsigned long);
void recursiveGetPartition(unsigned long ,unsigned long ,int );
char* replaceZeros(char *);
signed long long get2sCompliment(signed long long,int );
int tokenIt(char *,char** ,char** );
unsigned long long getIndexesFromRoot(int);
void printStandardMaceValues(unsigned long );
void scanMFT(unsigned long ,char*);
unsigned long getStartMFTRef(unsigned long long *,signed long long *,unsigned long long*,unsigned long );
void scanAllMFT(signed long long *,unsigned long long *);
void printFileNameMaceValues(unsigned long );
void printIndexMaceValues(int boundaryCheck);
void lookUpMFT(unsigned long mft);
signed long long getVCN(unsigned int ,unsigned int );
void printDataRun(unsigned long);
void saveLogFile(int);
void getLogFile(int);

BOOL getLoadDriverPriv()
{
	HANDLE hToken;
	LUID huid;
	LUID_AND_ATTRIBUTES priv;
	TOKEN_PRIVILEGES tp;

	if(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
	{

		if(LookupPrivilegeValueA(NULL, "SeLoadDriverPrivilege", &huid))
		{
			priv.Attributes = SE_PRIVILEGE_ENABLED;
			priv.Luid = huid;
			
			tp.PrivilegeCount = 1;
			tp.Privileges[0] = priv;

			if(AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL))
			{
				return TRUE;
			}
		}
	}
	return FALSE;
}

BOOL setupRegistry()
{
	HKEY hkey;
	DWORD val;
	char *imgName = "System32\\DRIVERS\\"DRV_FILENAME;

	if(RegCreateKeyA(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\"DRV_NAME, &hkey) != ERROR_SUCCESS)
		return FALSE;

	
	val = 1;
	if(RegSetValueExA(hkey, "Type", 0, REG_DWORD, (PBYTE)&val, sizeof(val)) != ERROR_SUCCESS)
		return FALSE;

	if(RegSetValueExA(hkey, "ErrorControl", 0, REG_DWORD, (PBYTE)&val, sizeof(val)) != ERROR_SUCCESS)
		return FALSE;
	
	val = 3;
	if(RegSetValueExA(hkey, "Start", 0, REG_DWORD, (PBYTE)&val, sizeof(val)) != ERROR_SUCCESS)
		return FALSE;

	
	if(RegSetValueExA(hkey, "ImagePath", 0, REG_EXPAND_SZ, (PBYTE)imgName, strlen(imgName)) != ERROR_SUCCESS)
		return FALSE;

	return TRUE;
}

BOOL loadDriver()
{
	// call ntdll APIs
	HMODULE hntdll;
	ANSI_STRING aStr;
	UNICODE_STRING uStr;

	NTSTATUS (WINAPI * _RtlAnsiStringToUnicodeString)
		(PUNICODE_STRING  DestinationString,
		 IN PANSI_STRING  SourceString,
		 IN BOOLEAN);

	VOID (WINAPI *_RtlInitAnsiString)
		(IN OUT PANSI_STRING  DestinationString,
		 IN PCHAR  SourceString);

	NTSTATUS (WINAPI * _ZwLoadDriver)
		(IN PUNICODE_STRING DriverServiceName);

	NTSTATUS (WINAPI * _ZwUnloadDriver)
		(IN PUNICODE_STRING DriverServiceName);

	VOID (WINAPI * _RtlFreeUnicodeString)
		(IN PUNICODE_STRING  UnicodeString);


	hntdll = GetModuleHandleA("ntdll.dll");
			
	*(FARPROC *)&_ZwLoadDriver = GetProcAddress(hntdll, "NtLoadDriver");

	*(FARPROC *)&_ZwUnloadDriver = GetProcAddress(hntdll, "NtUnloadDriver");
				
	*(FARPROC *)&_RtlAnsiStringToUnicodeString = 
			GetProcAddress(hntdll, "RtlAnsiStringToUnicodeString");

	*(FARPROC *)&_RtlInitAnsiString = 
			GetProcAddress(hntdll, "RtlInitAnsiString");

	*(FARPROC *)&_RtlFreeUnicodeString = 
			GetProcAddress(hntdll, "RtlFreeUnicodeString");

	if(_ZwLoadDriver && _ZwUnloadDriver && _RtlAnsiStringToUnicodeString &&
	   _RtlInitAnsiString && _RtlFreeUnicodeString)
	{
		_RtlInitAnsiString(&aStr, 
		"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"DRV_NAME);
						
		if(_RtlAnsiStringToUnicodeString(&uStr, &aStr, TRUE) != STATUS_SUCCESS)
			return FALSE;
		else
		{
			if(_ZwLoadDriver(&uStr) == STATUS_SUCCESS)
			{
				_RtlFreeUnicodeString(&uStr);
				return TRUE;
			}
			_RtlFreeUnicodeString(&uStr);
		}
	}

	return FALSE;
}

void cleanupDriver(void)
{
	char sysDir[MAX_PATH + 1];
	GetSystemDirectoryA(sysDir, MAX_PATH);
	strncat(sysDir, "\\drivers\\"DRV_FILENAME, MAX_PATH);
	DeleteFileA(sysDir);

	RegDeleteKeyA(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\"DRV_NAME"\\Enum");
	RegDeleteKeyA(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\"DRV_NAME);
}

BOOL unloadDriver()
{
	// call ntdll APIs
	HMODULE hntdll;
	ANSI_STRING aStr;
	UNICODE_STRING uStr;

	NTSTATUS (WINAPI * _RtlAnsiStringToUnicodeString)
		(PUNICODE_STRING  DestinationString,
		 IN PANSI_STRING  SourceString,
		 IN BOOLEAN);

	VOID (WINAPI *_RtlInitAnsiString)
		(IN OUT PANSI_STRING  DestinationString,
		 IN PCHAR  SourceString);

	NTSTATUS (WINAPI * _ZwLoadDriver)
		(IN PUNICODE_STRING DriverServiceName);

	NTSTATUS (WINAPI * _ZwUnloadDriver)
		(IN PUNICODE_STRING DriverServiceName);

	VOID (WINAPI * _RtlFreeUnicodeString)
		(IN PUNICODE_STRING  UnicodeString);


	hntdll = GetModuleHandleA("ntdll.dll");
			
	*(FARPROC *)&_ZwLoadDriver = GetProcAddress(hntdll, "NtLoadDriver");

	*(FARPROC *)&_ZwUnloadDriver = GetProcAddress(hntdll, "NtUnloadDriver");
				
	*(FARPROC *)&_RtlAnsiStringToUnicodeString = 
			GetProcAddress(hntdll, "RtlAnsiStringToUnicodeString");

	*(FARPROC *)&_RtlInitAnsiString = 
			GetProcAddress(hntdll, "RtlInitAnsiString");

	*(FARPROC *)&_RtlFreeUnicodeString = 
			GetProcAddress(hntdll, "RtlFreeUnicodeString");

	if(_ZwLoadDriver && _ZwUnloadDriver && _RtlAnsiStringToUnicodeString &&
	   _RtlInitAnsiString && _RtlFreeUnicodeString)
	{

		_RtlInitAnsiString(&aStr, 
		"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"DRV_NAME);
						
		if(_RtlAnsiStringToUnicodeString(&uStr, &aStr, TRUE) != STATUS_SUCCESS)
			return FALSE;
		else
		{
			if(_ZwUnloadDriver(&uStr) == STATUS_SUCCESS)
			{
				_RtlFreeUnicodeString(&uStr);
				return TRUE;
			}
			_RtlFreeUnicodeString(&uStr);
		}
	}

	return FALSE;
}


void uninstallDriver(void)
{
	char drvFullPath[MAX_PATH+1];
	char *filePart;
	HANDLE hFile;
	char sysDir[MAX_PATH + 1];

	ZeroMemory(drvFullPath, MAX_PATH);		
	GetFullPathNameA(DRV_FILENAME, MAX_PATH, drvFullPath, &filePart);

	hFile= CreateFileA(drvFullPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
								FILE_ATTRIBUTE_NORMAL, 0);
	if(hFile == INVALID_HANDLE_VALUE)
	{
		printf("Cannot find required driver file %s\n", drvFullPath);
		return;
	}
	else
	{
		CloseHandle(hFile);

		GetSystemDirectoryA(sysDir, MAX_PATH);
		strncat(sysDir, "\\drivers\\"DRV_FILENAME, MAX_PATH);
		CopyFileA(drvFullPath, sysDir, TRUE);

		if(!getLoadDriverPriv())
		{
			printf("Error getting load driver privilege!\n");
		}
		else
		{
			if(!setupRegistry())
			{
				printf("Error setting driver registry keys!\nMake sure you are running this as Administrator.\n");
			}
			else
			{
				if(unloadDriver())
					printf("Support driver successfully unloaded.\n");
				else
					printf("Unload support driver failed.  It is probably not loaded.\n");
			}
		}
		cleanupDriver();
	}
}

HANDLE openDriver(void)
{
	HANDLE hDevice;
	HANDLE hFile;
	char drvFullPath[MAX_PATH+1];
	char *filePart;
	char sysDir[MAX_PATH + 1];

	hDevice = CreateFileA("\\\\.\\"DRV_NAME, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
		   				 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

	if(hDevice == INVALID_HANDLE_VALUE)
	{		


		ZeroMemory(drvFullPath, MAX_PATH);		
		GetFullPathNameA(DRV_FILENAME, MAX_PATH, drvFullPath, &filePart);
		
		hFile= CreateFileA(drvFullPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
									FILE_ATTRIBUTE_NORMAL, 0);
		if(hFile == INVALID_HANDLE_VALUE)
		{
			printf("Cannot find required driver file %s\n", drvFullPath);
			return INVALID_HANDLE_VALUE;
		}
		else
		{
			CloseHandle(hFile);

			GetSystemDirectoryA(sysDir, MAX_PATH);
			strncat(sysDir, "\\drivers\\"DRV_FILENAME, MAX_PATH);
			CopyFileA(drvFullPath, sysDir, TRUE);

			if(!getLoadDriverPriv())
			{
				printf("Error getting load driver privilege!\n");
			}
			else
			{
				if(!setupRegistry())
				{
					printf("Error setting driver registry keys!\nMake sure you are running this as Administrator.\n");
				}
				else
				{
					loadDriver();
					hDevice = CreateFileA("\\\\.\\"DRV_NAME, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
		   				 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
					if(hDevice == INVALID_HANDLE_VALUE)
					{
						printf("Error loading kernel support driver!\nMake sure you are running this as Administrator.\n");
					}
				}
			}
			cleanupDriver();
		}
	}
	
	return hDevice;
}

DWORD DoDeviceIoCtl(DWORD dwIoCtl, DWORD dwDiskObjOrdinal, 
					BOOLEAN bIsRawDisk, ULONGLONG ullSectorNumber, PVOID *pBuf)
{
	CHAR	szDriverPath[MAX_PATH];
	HANDLE	hDevice;
	DWORD	dwStatus, Size = 512, Bytes;
	DISK_LOCATION	dlInfo;
	PVOID	pMem = NULL;
	PBYTE	pByte;
	OFSTRUCT	ofReOpenBuff;
	DWORD		i;
	char	c;

	hDevice = openDriver();

	if (hDevice == INVALID_HANDLE_VALUE) {
		printf("Can't Open Driver\n");
	}

	dlInfo.bIsRawDiskObj = bIsRawDisk;
	dlInfo.dwDiskOrdinal = dwDiskObjOrdinal;
	dlInfo.ullSectorNum  = ullSectorNumber;
	

	do
	{
		if (dwIoCtl == IOCTL_SECTOR_WRITE) {
			Size += sizeof(DISK_LOCATION);
		}

		pMem = malloc(Size);

		// A very ugly hack to transfer disk location data and input buffer both for write operations
		// Came to know about bug of write operations very late, So instead of handling mapping user address into kernel
		// address space, I did this hack, Will fix it in future
	
		if (!pMem)
			return ERROR_NOT_ENOUGH_MEMORY;

		memset(pMem, 0x00, Size);
		
		if (dwIoCtl == IOCTL_SECTOR_WRITE) {
			pByte = (PBYTE) ((ULONG)pMem + sizeof(DISK_LOCATION));
			i = 0;
			printf("Please type the data you want to write to the sector (input redirection is a better option)\nInput Data: \n");

			do{
				c = getc(stdin);
				pByte[i] = c;
				i++;
			}while ((i < Size) && (c != EOF));
		}
		if (dwIoCtl == IOCTL_SECTOR_WRITE) {
			memcpy(pMem, &dlInfo, sizeof(dlInfo));
			if(DeviceIoControl(hDevice, dwIoCtl, pMem, Size, NULL, 0, &Bytes, NULL))
				break;
		} else {
			if(DeviceIoControl(hDevice, dwIoCtl, &dlInfo, sizeof(dlInfo), pMem, Size, &Bytes, NULL))
				break;
		}
		
		dwStatus = GetLastError();
		printf ("DeviceIoControl Failed and error code is %d\n", dwStatus);
		return -1;
		if (dwIoCtl == IOCTL_SECTOR_WRITE) {
			Size -= sizeof(DISK_LOCATION);
		}
		free(pMem);
		pMem = NULL;
		Size = Size * 2;
	}while(dwStatus == ERROR_INSUFFICIENT_BUFFER);

	if (dwIoCtl == IOCTL_SECTOR_READ && pMem) {
		pByte = (PBYTE) pMem;
		i = 0;
		c = 0;
	//	printf("Displaying the data read from the sector (in hexadecimal, output redirection can also work)\nOutput Data: \n");
		/*do{
			c = pByte[i];
			//putc(c, stdout);
			printf("0x%-02X ", c & 0x00FFUL);

			if (!(i+1)%0x10) {
				printf ("\n");
			}
			i++;
		}while (i < Size);*/
	}

	*pBuf = pMem;
	return Size;
}
VOID PrintUsage()
{
	
	return;
}

int  get(unsigned long  sector,char**buf,int count)
{
	int			argIndex;
	BOOLEAN		bIsRawDisk, bReadWrite, bLoadDriver = TRUE;
	DWORD		dwDiskObjOrdinal = -1;
	ULONGLONG	ullSectorNumber = -1;
	DWORD		dwSize = 512;
	PVOID		pBuf = NULL;
	int u=0;
	int rp=0;
	
/*	if( argc < 2 || strcmp(argv[1], "/?") == 0 ) {
        PrintUsage();
        return (0);
    }

	argIndex = 1;

	for (argIndex = 1; argIndex < argc; argIndex++)
	{
		if (!strcmp(argv[argIndex], "/disk") || !strcmp(argv[argIndex], "/partition")) {
			if (dwDiskObjOrdinal == -1) {
				bIsRawDisk = strcmp(argv[argIndex], "/disk") ? FALSE : TRUE;
				argIndex++;
				if (argIndex < argc) {
					char *endptr;
					dwDiskObjOrdinal = strtoul(argv[argIndex], &endptr, 10);
				} else {
					PrintUsage();
					return -1;
				}
			} else {
				PrintUsage();
				return -1;
			}
		} else if (!strcmp(argv[argIndex], "/read") || !strcmp(argv[argIndex], "/write")) {
			if (ullSectorNumber == -1) {
				bReadWrite = strcmp(argv[argIndex], "/read") ? FALSE : TRUE;
				argIndex++;
				if (argIndex < argc) {
					char *endptr;
					ullSectorNumber = _strtoui64(argv[argIndex], &endptr, 10);
				}
			} else {
				PrintUsage();
				return -1;
			}

		} else if (!strcmp(argv[argIndex], "/unload")) {
			bLoadDriver = FALSE;
		} else {
			PrintUsage();
			return -1;
		}
	}
*/
	bLoadDriver = TRUE;
	if (!bLoadDriver) {
		uninstallDriver();
		return 0;
	} else if (sector == -1){
		PrintUsage();
		return -1;

	}
*buf=(char*)calloc(count,1);
	while(u<count/512)
	{
	rp=DoDeviceIoCtl(IOCTL_SECTOR_READ, 
				0, TRUE, sector+u, &pBuf);
	
	if(rp==-1)
		return 0;
	 memcpy((*buf+(u*512)),pBuf,512);
	 u++;
	}
	return 1;
	/*if (!pBuf)
		free(pBuf);
*/
	
}





#define BPERL  16 /* byte/line for dump */

void dumpIt(char *data_p,  int count)
{
    
    unsigned byte1, byte2;
	FILE *p;
	int i=0;
	p=fopen("log.txt","a+b");
	fflush(p);
    while(i<count )
    {
        //for(byte1 = 0; byte1 < BPERL; byte1++)
        //{
			
            fprintf(p,"%c", data_p[i]);
            i++;
    }
       //printf("\t");
        /*for(byte2 = 0; byte2 < byte1; byte2++)
        {
            if(data[byte2] < ' ')
                fprintf(p,".");
            else
                fprintf(p,"%c", data[byte2]);
        }*/

        //fprintf(p,"\n");
		fclose(p);

}






char* mbr,*boot,*pte;
unsigned long *bootSectors,firstMFT,universalMFTEntry=0;
 unsigned i;int negativeFlag=0,bootIndex;
 FILE* IndexF, * vc,*index,*MFT;
 signed long long *mftVCNs;
unsigned long long *mftRunLength;
short int clusterSize=0;
short int recordSize=0;  //Index record Size in cluster
short int bytesSector=0; //Bytes per sector
short int mftSize=0;
 
int __cdecl main(int argc, char* argv[])
{
char *path;
char *tokenCopy;

char*tok=NULL;
char*del=NULL;
char*f="file";
unsigned long mft=0;
unsigned long mftAdd=0;
unsigned long long fileReference=0; 
int dataOffset;

mftVCNs=(signed long long*)calloc(1,sizeof(signed long long));
mftRunLength=(unsigned long long*)calloc(1,sizeof(unsigned long long));
bootSectors=(unsigned long*)calloc(26,sizeof(unsigned long));
path=(char*)calloc(128,sizeof(char));
recursiveGetPartition(0,0,2);
IndexF=fopen("Shray.txt","w");
vc=fopen("vc.txt","w");
index=fopen("index.txt","w");



if(!strcmp(argv[1],"s",1))
{
	bootIndex=((int)argv[2][0])-97;
}
else
bootIndex=atoi(argv[3]);

printf("BootIndex %d\n",bootIndex);

mftAdd= getMFT(bootSectors[bootIndex],bootIndex)-10;
printf("RootMFT %lu\n",mftAdd+10);	
	
	dataOffset=locateIndex(mftAdd,128,0);                 //MFT runs
	printf("dataOffset %d\n",dataOffset);

	if(dataOffset)
	{
		char byte=*(char*)(mbr+dataOffset+8);
		int resFlag=(int)byte;
		if(resFlag==1)
		{
			int i=0;
			unsigned int offRun=*(unsigned short int*)(mbr+dataOffset+32);
			unsigned long long runLength;
			do{

			signed long long vcn=getNextVCN(&offRun,dataOffset,&runLength);
			mftVCNs[i]=	negativeFlag&&vcn>0?-vcn:vcn;
			mftRunLength[i]=runLength;
			
			i++;	
			mftVCNs=realloc(mftVCNs,(i+1)* sizeof(signed long long));
			mftRunLength=realloc(mftRunLength,(i+1)* sizeof(unsigned long long));
			printf("Next MFT VCN %lli Length= %llu\n",mftVCNs[i-1],mftRunLength[i-1]);
			}
			while(mftVCNs[i-1]!=0);
		}

	}
//firstMFT=mftVCNs[0]*8+bootSectors[bootIndex];
firstMFT=mftVCNs[0]*clusterSize+bootSectors[bootIndex];

	if(!strncmp(argv[1],"t",1))
	{
		//printf("%lu\n",strtol(argv[2],NULL,10));
		
		printFileNameMaceValues(strtol(argv[2],NULL,10));
		
		printStandardMaceValues(strtol(argv[2],NULL,10));
		fclose(IndexF);
		fclose(vc);
		fclose(index);

		exit(0);
		
	}

	if(!strncmp(argv[1],"p",1))
	{
	printf("%lu\n",strtol(argv[4],NULL,10));	
	lookUpFolderDirectory("file",strtol(argv[2],NULL,10),bootIndex,strtol(argv[4],NULL,10));
	fclose(IndexF);
	fclose(vc);
	fclose(index);

	exit(0);
	}

if(!strncmp(argv[1],"c",1))
	{
	lookUpMFT(strtol(argv[2],NULL,10));
	fclose(IndexF);
	fclose(vc);
	fclose(index);
	exit(0);
	}

if(!strncmp(argv[1],"d",1))
	{
	
	fclose(IndexF);
	fclose(vc);
	fclose(index);
	exit(0);
	}

if(!strcmp(argv[1],"l",1))
{
	
	FILE * f2;
	saveLogFile(1);
	
	fclose(IndexF);
	fclose(vc);
	fclose(index);
	exit(0);
}
MFT=fopen("FileName.txt","w");	
	

	
	printf("Boot Index %lu\n",bootSectors[bootIndex]);
	
	
scanAllMFT(mftVCNs,mftRunLength);
fclose(IndexF);
fclose(vc);
fclose(index);
fclose(MFT);
	
    return 0;
}


void printDataRun(unsigned long mftNo)
{
	short int offset=0;
	unsigned long long sectorNo;
	//free(mbr);
	offset=locateIndex(mftNo,128,1);
	//printf("%d\n",*(unsigned short int*)(mbr+offset+8));
	if(offset!=0 && *(unsigned short int*)(mbr+offset+8)!=0)
	{
	sectorNo=getVCN(*(unsigned short int*)(mbr+offset+32),offset)*clusterSize+bootSectors[bootIndex];
	printf("SectorNo %llu\n",sectorNo);
	
	}

	

}
int tokenIt(char *path,char** tok,char** del)
{
	
	int j=0;
	char *p;
//	printf("%u  %u",del,*del);
	if(*tok!=NULL)
		path=*tok;

//	free(*del);
//	free(*tok);
	*del=NULL;
	*tok=NULL;
	while(*(path) !='\0' && *(path)!=NULL)
	{
		if(*(path)=='\\'||*(path+1)=='\0')
		{
			if(*tok==NULL)
				*tok= path+1;
			else 
			{
				if(*(path+1)=='\0')
					j=1;
				else
					j=0;

				*del=(char*)calloc(path-(*tok)+1+j,1);
				memcpy(*(del),*tok,path-(*tok)+j);
				*(*del+(path-(*tok)+j)+1)='\0';
				
				return 1;
			}
		}
		
			path++;
	}
return 0;
	//*tok=NULL;
}

unsigned long getMFT(unsigned long startLBA,int bootIndex)  // 8,63,10 hard-coded
{
	unsigned long dataMft;
	char mSize;
	printf("startLBA %lu \n",startLBA);
	free(mbr);
	get(startLBA,&mbr,512);
	clusterSize=*((char*)(mbr+13));
	recordSize=*((char*)(mbr+68));
	bytesSector=*((unsigned short int*)(mbr+11));
	mSize=*((char*)(mbr+64));
	if(mSize&0x80)
	{
		
		mSize=mSize^0xFF;
		mSize=mSize+1;
		mSize=mSize&0x7F;
		mftSize=2<<(mSize-1);
	}
	else
		mftSize=clusterSize*bytesSector;

	printf("Cluster and Record Size, Bytes/Sector %d %d %d %d\n",clusterSize,recordSize,bytesSector,mftSize);
	dataMft=*((unsigned long*)(mbr+48));  //63 to be calculated, 2 sector for each MFT - > 10 for root '.' MFT
	//dataMft=(dataMft*8)+bootSectors[bootIndex]+10;
	dataMft=(dataMft*clusterSize)+bootSectors[bootIndex]+10;
	return dataMft;
}
unsigned long long lookUpFolderDirectory(char *f,unsigned long mft,int bootIndex,unsigned long parentMFTSector)
{
	unsigned int startIndex,start,fflag=0;
	unsigned _int64 startVCN;
	unsigned long long childVCN;
	unsigned long long run_length,var=0;
	unsigned _int64 endVCN;
	unsigned int offsetRunList;
	unsigned long startEntry,flagGetStart;
	unsigned long endEntry;
	unsigned short flag;
	unsigned short int lengthEntry;
	unsigned long long offsetToCluster,mftToReturn,vcnNumber;
	unsigned long long lastOffset=0;
	char*name,g;
	char byte;
	int boundaryCheck,indexOffset;
	
	short int length,attListOffset;
	printf("inlookup");	
	printf("BootSector = %lu \n",bootSectors[bootIndex]);
	startIndex=locateIndex(mft,160,0); 
	start=locateIndex(mft,144,1); //Index Root

	
		if(start!=0)
			getIndexesFromRoot(f,start,parentMFTSector);

		if(startIndex==0)
			return;
		
		
	
	//dumpIt(mbr,bytesSector);
	
	startVCN=*(unsigned long long*)(mbr+startIndex+16);
	endVCN=*(unsigned long long *)(mbr+startIndex+24);
	offsetRunList=*(unsigned short int*)(mbr+startIndex+32);
	
	
		printf("offsetATT %lu\n",*(unsigned  long*)(mbr+startIndex));
		printf("startIndex %lu \n startVCN %llu \n endVCN %llu \n offsetRunList %d \n",startIndex,startVCN,endVCN,offsetRunList);

	offsetToCluster = (getNextVCN(&offsetRunList,startIndex,&run_length)*clusterSize)+bootSectors[bootIndex];  //Changed Default 8 to clusterSize
	
	if(offsetToCluster!=0)
	{	
		fputs("\nStart of Run\n",index);
		fputs("\nStart of Run\n",vc);
	}
	
	while(offsetToCluster!=0)
	{

		if(negativeFlag)
		{
			offsetToCluster=lastOffset-offsetToCluster;
			printf("Negative EntryIndex %llu offsetToCluster %lli\n",lastOffset,offsetToCluster);
		}
		else
		{
			offsetToCluster+=lastOffset;
			printf("Positive EntryIndex %llu offsetToCluster %lli\n",lastOffset,offsetToCluster);
		}
	
		lastOffset=offsetToCluster;
		var=0;
		
		//fprintf(fil,"%lu \n",mft);
	
		while(var<run_length)
		{		
		int ui=0;
		printf("offsetToCluster %llu\n Last Offset %lli\n var= %llu run= %llu\n",offsetToCluster,lastOffset,var,run_length);
		get(offsetToCluster,&boot,recordSize*clusterSize*bytesSector);  //Chnaged Default 4096 to Index record * Cluster Size

		if(!isValidIndex())
		{
			//fclose(fil);
			return;
		}

		startEntry=*(unsigned long*)(boot+24);
		flagGetStart=*(unsigned long*)(boot+24);
		endEntry=*(unsigned long*)(boot+28);
		vcnNumber=*(unsigned long long*)(boot+16);
		printf("VCNNumber %llu\n",vcnNumber);
		indexOffset=0;
		fflag=0;
		while(1){
			
			while(indexOffset<= recordSize*clusterSize*bytesSector && ((*(unsigned long long*)(boot+indexOffset)& 0x0000FFFFFFFFFFFF)) != parentMFTSector)
			{
			indexOffset+=8;
			
			}
			//printf("ToCOmpare %llu %lu %d %lu\n",(*(unsigned long long*)(boot+indexOffset)& 0x0000FFFFFFFFFFFF),parentMFTSector,indexOffset,offsetToCluster);
			
			startEntry=indexOffset-16-24;
			flagGetStart=startEntry;
			lengthEntry=*(unsigned short int*)(boot+24+startEntry+8);
			if(startEntry+lengthEntry>=endEntry&&!fflag)
			{
				printf("EndOfAllocated\n");
				fflag=1;
			}
			if(indexOffset>recordSize*clusterSize*bytesSector)
				break;

			printf("Before Boundary Check %d %d\n",startEntry,endEntry);
			boundaryCheck=24+startEntry+16+64;
			if(boundaryCheck>=recordSize*clusterSize*bytesSector)
			{
				printf("got in extension\n");
				break;
			}
			printf("After Boundary Check %d\n",boundaryCheck);
			printf("FileNo in Hex %0X16\n",(boot+24+startEntry));
			printf("FileReferenceNoToMFT %lu %d\n",fileRefToMFTSector((*(unsigned long long*)(boot+24+startEntry)& 0x0000FFFFFFFFFFFF)),(*(unsigned long long*)(boot+24+startEntry)& 0xFFFF000000000000)>>48);
			
			lengthEntry=*(unsigned short int*)(boot+24+startEntry+8);
			
			flag=*(unsigned short*)(boot+24+startEntry+12);
			//startEntry+=lengthEntry;
			flagGetStart+=lengthEntry;
			
			byte=*(char*)(boot+boundaryCheck);
			
			length=(int)byte;
			
		
			
			if(length>0){

			name=(char*)calloc((length*2),1);
			memcpy(name,(boot+boundaryCheck+2),length*2);
			name=replaceZeros(name,length*2);
			name[length]='\0';

			printf("IndexName %s\n",name);
			
			fputs(name,IndexF);
			fputs("\n",IndexF);
			printIndexMaceValues(boundaryCheck);
			
			printf("%d \n",flag);
			
			}
			if(flag==1)
			{
			
				childVCN=*(unsigned long long*)(boot+flagGetStart+24-8);
				printf("FL+24 %d %d %d\n",flagGetStart+24,startEntry,lengthEntry);
				if((flagGetStart+24)%bytesSector==0)
				{
					childVCN=childVCN&0x0000FFFFFFFFFFFF;
					printf("yes\n");
				}
				printf("Child VCN %llu\n",childVCN);
				printf("ParentChild %llu %llu %d\n",vcnNumber,childVCN,ui);
			
			}
			
			if(length>0)
			free(name);

			
			ui++;
			indexOffset+=8;
		}
		
		//while(flag!=2&&length!=0&&startEntry<endEntry);
		offsetToCluster=offsetToCluster+(recordSize*clusterSize);
		var++;
	}
		
		offsetToCluster=getNextVCN(&offsetRunList,startIndex,&run_length)*clusterSize;

	}
	//fclose(fil);
return 0;
}

unsigned long long getIndexesFromRoot(char*f,int offset,unsigned long parentMFTSector)
{
	unsigned long contentLength;
	unsigned long startEntry;
	unsigned long endEntry,flagGetStart;
	unsigned long long mftToReturn,childVCN;
	unsigned long flag,fflag=0;
	char byte;
	unsigned short int lengthEntry,indexOffset=0;
	int boundaryCheck;
	int length;
	char*name;
	
	contentLength=*(unsigned long*)(mbr+offset+16);
	offset+=*(unsigned short int*)(mbr+offset+20);
	startEntry=*(unsigned long*)(mbr+offset+16);
	flagGetStart=*(unsigned long*)(mbr+offset+16);
	endEntry=*(unsigned long*)(mbr+offset+16+8);
	printf("Offset %d\n",offset);
	indexOffset=offset;
	printf("VCNNumber IndexRoot\n");

	while(1){
			
			while(indexOffset<=mftSize && ((*(unsigned long long*)(mbr+indexOffset)& 0x0000FFFFFFFFFFFF)) != parentMFTSector)
			{
			
			indexOffset+=8;
			
			}
			printf("ParentGot %lu %d\n",parentMFTSector,indexOffset);
			
			startEntry=indexOffset-16-24;
			flagGetStart=startEntry;
			if(startEntry>endEntry&&!fflag)
			{
				printf("EndOfAllocated\n");
				fflag=1;
			}
			if(indexOffset>mftSize)
				break;

			printf("Before Boundary Check %d %d\n",startEntry,endEntry);
			boundaryCheck=24+startEntry+16+64;
			printf("After Boundary Check %d\n",boundaryCheck);
			printf("FileNo in Hex %0X16\n",(mbr+24+startEntry));
			printf("FileReferenceNoToMFT %lu %d\n",fileRefToMFTSector((*(unsigned long long*)(mbr+24+startEntry)& 0x0000FFFFFFFFFFFF)),(*(unsigned long long*)(mbr+24+startEntry)& 0xFFFF000000000000)>>48);
			lengthEntry=*(unsigned short int*)(mbr+24+startEntry+8);
			printf("%d %d\n",startEntry,lengthEntry);
			flag=*(unsigned short*)(mbr+24+startEntry+12);
			
			flagGetStart+=lengthEntry;
			if(boundaryCheck>=mftSize)
			{
				printf("got in extension\n");
				break;
			}
			byte=*(char*)(mbr+boundaryCheck);
			length=(int)byte;
			
		
			if(length>0){

			name=(char*)calloc((length*2),1);
			memcpy(name,(mbr+boundaryCheck+2),length*2);
			name=replaceZeros(name,length*2);
			name[length]='\0';

			printf("IndexName %s\n",name);
			
			
			//printIndexMaceValues(boundaryCheck);
			
			printf("%d \n",flag);
			}

			if(flag==1)
			{
			
				childVCN=*(unsigned long long*)(mbr+flagGetStart+24-8);
				
				printf("Child VCN %llu\n",childVCN);
				printf("ParentChild %s %d\n","IndexRoot",childVCN);
			
			}
			free(name);
			
			indexOffset+=8;
		}


}
char* replaceZeros(char *name,int length)
{
	
	int i=0,j=0;
	char* nameR=(char*)calloc((length/2)+10,1);
	unsigned short int byte;
	while(i<length)
	{
		/*byte=*(nameR+i);
		byte=byte&&0x00FF;
		printf("BYTE = %d char= %c \n",byte,*(nameR+i));
		*/
		/*if(j>6)
		{
			*(nameR+j)='\0';
			return nameR;
		}*/
		if(*(name+i)!='\0')//&&((byte>=97 && byte<=122)|| (byte>=65 &&byte<=90)||byte==46 ))
		{
			*(nameR+j)=*(name+i);
			j++;
		}
		i++;
	}
	*(nameR+j)='\0';
	return nameR;
}
signed long long getNextVCN(unsigned int* offsetRunList,unsigned int startIndex,unsigned long long *run_length)  //decode run-list
{
	unsigned short int nibble;
	char c,*arr=NULL;
	unsigned short int run=0;
	unsigned short int runLength=0;
	signed long long offsetToCluster=0;
	unsigned short int offset;
	unsigned long long flip=0xFFFFFFFFFFFFFFFF;
	negativeFlag=0;
	
	
	c=*(char*)(mbr+(*offsetRunList)+startIndex);
	nibble=(unsigned short int)c;
	
	if(nibble==0)
		return 0;

	runLength= nibble & 0x000F;
	run=runLength;
	

	offset=nibble & 0x00F0;
	offset=offset>>4;
	

	arr=(char*)calloc((short int)runLength,1);
	
	memcpy(arr,(mbr+(*offsetRunList)+1+startIndex),(unsigned short int)runLength);
	flip=flip>>((8-runLength)*8);
	runLength=*(unsigned long long*)arr;
	runLength=runLength&flip;
	flip=0xFFFFFFFFFFFFFFFF;
	
	free(arr);
	//printf("runLength %d\n",runLength);
	*run_length=runLength;
	arr=(char*)calloc(offset,1);
	memcpy(arr,mbr+(*offsetRunList)+1+run+startIndex,offset);
	

	flip=flip>>((8-offset)*8);
	
	offsetToCluster=*(signed long long*)arr;
	
	offsetToCluster=offsetToCluster&flip;
	
	if(arr[offset-1]<0)
	{
		offsetToCluster=get2sCompliment(offsetToCluster,offset);
		negativeFlag=1;
	}

	
	*offsetRunList=(*offsetRunList)+run+offset+1;
	free(arr);
	printf("Next VCN Call Return %lli\n",offsetToCluster);
	return offsetToCluster;
}


signed long long getVCN(unsigned int offsetRunList,unsigned int startIndex)  //decode run-list
{
	unsigned short int nibble,run;
	char c,*arr=NULL;
	
	signed long long offsetToCluster=0;
	unsigned short int offset;
	unsigned long long flip=0xFFFFFFFFFFFFFFFF;
	negativeFlag=0;
	
	c=*(char*)(mbr+(offsetRunList)+startIndex);
	nibble=(unsigned short int)c;
	if(nibble==0)
		return 0;
	
	run= nibble & 0x000F;
	

	offset=nibble & 0x00F0;
	offset=offset>>4;

	arr=(char*)calloc(offset,1);
	memcpy(arr,mbr+(offsetRunList)+1+run+startIndex,offset);
	

	flip=flip>>((8-offset)*8);
	
	offsetToCluster=*(signed long long*)arr;
	
	offsetToCluster=offsetToCluster&flip;
	
	if(arr[offset-1]<0)
	{
		offsetToCluster=get2sCompliment(offsetToCluster,offset);
		negativeFlag=1;
	}

	
	offsetRunList=(offsetRunList)+run+offset+1;
	free(arr);
	printf("Next VCN Call Return %lli\n",offsetToCluster);
	return offsetToCluster;
}
unsigned  int locateIndex(unsigned long mft,int indexType,int skipLoad)
{
	unsigned  int offsetATT;
	unsigned long type;
	unsigned int offset;
	int attListFlag=0;
	
	printf("locate index in %lu \n",mft);
	if(skipLoad==0)
		get(mft,&mbr,mftSize);
	
	offsetATT=*(unsigned short int*)(mbr+20);
	printf("Offset to First Attribute %d \n",offsetATT);
	while(offsetATT<mftSize)
	{	
		type=*(unsigned long*)(mbr+offsetATT);
		printf("Found Type %d\n",type);
		
		if(type==indexType)
		{
			
			break;
		}
		if(*(unsigned int*)(mbr+offsetATT+4)==0)
			return 0;
		if(attListFlag==1)
			offsetATT+=*(unsigned short int*)(mbr+offsetATT+4);
		else
		offsetATT+=*(unsigned int*)(mbr+offsetATT+4);
		
	}
	if(offsetATT>1024)
		return 0;
	else
	return offsetATT;

}

signed long long get2sCompliment(signed long long value,int length)
{
	signed long long temp;
	unsigned long long flip=0xFFFFFFFFFFFFFFFF;
	flip=flip>>((8-length)*8);
	
	temp=value^flip;
	temp=temp+0x0000000000000001;
	temp=temp&flip;
	//printf("%016X\n",temp);
	return temp;
}
void recursiveGetPartition(unsigned long sector,unsigned long extended,int j)
{
    char b;
	unsigned int g;
	
	free(mbr);
    get(sector,&mbr,512);
    

    for(i = 0; i < 4; i++)
    {
        pte = mbr + 446 + 16 * i;
      	b=*(unsigned char*)(pte+4);
		g=(unsigned int)b;
	if(g==15||g==5)
	{
		printf("\nExtended %lu\n",extended);
		sector=extended+(*(unsigned long *)(pte+8));
			if(extended==0)
				extended=*(unsigned long *)(pte+8);
			printf("\nReading Sector %lu\n",sector);
			recursiveGetPartition(sector,extended,j);
			break;
		
	}
	else
	{
	printf("Partition Type %d\n",*(char*)((pte+4)));
	printf("Bootable %d\n",*(unsigned char*)pte);

	printf("Sector size %lu\n",*(unsigned long*)(pte+12));
	printf("Size in Bytes %d GB\n",(*(unsigned long*)(pte+12))/2000000);
	printf("Start LBA %lu\n",sector);
	if(g==7)
	{
		bootSectors[j]=sector+*(unsigned long*)(pte+8);
		j++;
	}
	}
        
    }
}


void printStandardMaceValues(unsigned long mft)
{
	unsigned short contentOffset;
	FILETIME fc;
	SYSTEMTIME sc;
	SYSTEMTIME sc2;
	TIME_ZONE_INFORMATION tmz;

	int offset=locateIndex(mft,16,0);
	GetTimeZoneInformation(&tmz);

	if(offset!=0)
	{
	contentOffset=offset+*(unsigned short*)(mbr+offset+20);
	fc.dwHighDateTime=*(unsigned long*)(mbr+contentOffset+4);
	fc.dwLowDateTime=*(unsigned long*)(mbr+contentOffset);
	FileTimeToSystemTime(&fc,&sc2);
	SystemTimeToTzSpecificLocalTime(&tmz,&sc2,&sc);
	printf("cre %d/%d/%d : %d:%d:%d\n",sc.wMonth,sc.wDay,sc.wYear,sc.wHour,sc.wMinute,sc.wSecond);
	
	fc.dwHighDateTime=*(unsigned long*)(mbr+contentOffset+12);
	fc.dwLowDateTime=*(unsigned long*)(mbr+contentOffset+8);
	FileTimeToSystemTime(&fc,&sc2);
	SystemTimeToTzSpecificLocalTime(&tmz,&sc2,&sc);
	printf("Mod %d/%d/%d : %d:%d:%d\n",sc.wMonth,sc.wDay,sc.wYear,sc.wHour,sc.wMinute,sc.wSecond);

	
	fc.dwHighDateTime=*(unsigned long*)(mbr+contentOffset+20);
	fc.dwLowDateTime=*(unsigned long*)(mbr+contentOffset+16);
	FileTimeToSystemTime(&fc,&sc2);
	SystemTimeToTzSpecificLocalTime(&tmz,&sc2,&sc);
	printf("MFT %d/%d/%d : %d:%d:%d\n",sc.wMonth,sc.wDay,sc.wYear,sc.wHour,sc.wMinute,sc.wSecond);
	
	fc.dwHighDateTime=*(unsigned long*)(mbr+contentOffset+28);
	fc.dwLowDateTime=*(unsigned long*)(mbr+contentOffset+24);
	FileTimeToSystemTime(&fc,&sc2);
	SystemTimeToTzSpecificLocalTime(&tmz,&sc2,&sc);
	printf("Acc %d/%d/%d : %d:%d:%d\n",sc.wMonth,sc.wDay,sc.wYear,sc.wHour,sc.wMinute,sc.wSecond);

	
	}
}

void printFileNameMaceValues(unsigned long mft)
{
unsigned short contentOffset;
FILETIME fc;
	SYSTEMTIME sc;
	SYSTEMTIME sc2;
	TIME_ZONE_INFORMATION tmz;

int offset=locateIndex(mft,48,0);
GetTimeZoneInformation(&tmz);


if(offset!=0)
	{
	contentOffset=offset+*(unsigned short*)(mbr+offset+20);
	printf("GotCrea %llu\n",*(unsigned long long*)(mbr+contentOffset+8));
	/*fprintf(MFT," %llu",*(unsigned long long*)(mbr+contentOffset+16));
	fprintf(MFT," %llu",*(unsigned long long*)(mbr+contentOffset+24));
	fprintf(MFT," %llu\n",*(unsigned long long*)(mbr+contentOffset+32));
*/
	fc.dwHighDateTime=*(unsigned long*)(mbr+contentOffset+12);
	fc.dwLowDateTime=*(unsigned long*)(mbr+contentOffset+8);
	FileTimeToSystemTime(&fc,&sc2);
	SystemTimeToTzSpecificLocalTime(&tmz,&sc2,&sc);
	printf("cre %d/%d/%d : %d:%d:%d\n",sc.wMonth,sc.wDay,sc.wYear,sc.wHour,sc.wMinute,sc.wSecond);
	
	fc.dwHighDateTime=*(unsigned long*)(mbr+contentOffset+20);
	fc.dwLowDateTime=*(unsigned long*)(mbr+contentOffset+16);
	FileTimeToSystemTime(&fc,&sc2);
	SystemTimeToTzSpecificLocalTime(&tmz,&sc2,&sc);
	printf("Mod %d/%d/%d : %d:%d:%d\n",sc.wMonth,sc.wDay,sc.wYear,sc.wHour,sc.wMinute,sc.wSecond);

	
	fc.dwHighDateTime=*(unsigned long*)(mbr+contentOffset+28);
	fc.dwLowDateTime=*(unsigned long*)(mbr+contentOffset+24);
	FileTimeToSystemTime(&fc,&sc2);
	SystemTimeToTzSpecificLocalTime(&tmz,&sc2,&sc);
	printf("MFT %d/%d/%d : %d:%d:%d\n",sc.wMonth,sc.wDay,sc.wYear,sc.wHour,sc.wMinute,sc.wSecond);
	
	printf("GotLast %llu\n",*(unsigned long long*)(mbr+contentOffset+32));
	fc.dwHighDateTime=*(unsigned long*)(mbr+contentOffset+36);
	fc.dwLowDateTime=*(unsigned long*)(mbr+contentOffset+32);
	FileTimeToSystemTime(&fc,&sc2);
	SystemTimeToTzSpecificLocalTime(&tmz,&sc2,&sc);
	printf("Acc %d/%d/%d : %d:%d:%d\n",sc.wMonth,sc.wDay,sc.wYear,sc.wHour,sc.wMinute,sc.wSecond);

	
	
	
}

}



void printIndexMaceValues(int boundaryCheck)
{
	
	FILETIME fc;
	SYSTEMTIME sc;
	SYSTEMTIME sc2;
	TIME_ZONE_INFORMATION tmz;

	
	GetTimeZoneInformation(&tmz);

		
	fc.dwHighDateTime=*(unsigned long*)(boot+boundaryCheck-52);
	fc.dwLowDateTime=*(unsigned long*)(boot+boundaryCheck-56);
	FileTimeToSystemTime(&fc,&sc2);
	SystemTimeToTzSpecificLocalTime(&tmz,&sc2,&sc);
	printf("creString %0X16\n",*(unsigned long long*)(boot+boundaryCheck-52));
	printf("cre %d/%d/%d : %d:%d:%d\n",sc.wMonth,sc.wDay,sc.wYear,sc.wHour,sc.wMinute,sc.wSecond);
	
	
	fc.dwHighDateTime=*(unsigned long*)(boot+boundaryCheck-44);
	fc.dwLowDateTime=*(unsigned long*)(boot+boundaryCheck-48);
	FileTimeToSystemTime(&fc,&sc2);
	SystemTimeToTzSpecificLocalTime(&tmz,&sc2,&sc);
	printf("Mod %d/%d/%d : %d:%d:%d\n",sc.wMonth,sc.wDay,sc.wYear,sc.wHour,sc.wMinute,sc.wSecond);

	
	fc.dwHighDateTime=*(unsigned long*)(boot+boundaryCheck-36);
	fc.dwLowDateTime=*(unsigned long*)(boot+boundaryCheck-40);
	FileTimeToSystemTime(&fc,&sc2);
	SystemTimeToTzSpecificLocalTime(&tmz,&sc2,&sc);
	printf("MFT %d/%d/%d : %d:%d:%d\n",sc.wMonth,sc.wDay,sc.wYear,sc.wHour,sc.wMinute,sc.wSecond);
	
	fc.dwHighDateTime=*(unsigned long*)(boot+boundaryCheck-28);
	fc.dwLowDateTime=*(unsigned long*)(boot+boundaryCheck-32);
	FileTimeToSystemTime(&fc,&sc2);
	SystemTimeToTzSpecificLocalTime(&tmz,&sc2,&sc);
	printf("Acc %d/%d/%d : %d:%d:%d\n",sc.wMonth,sc.wDay,sc.wYear,sc.wHour,sc.wMinute,sc.wSecond);

}
void scanMFT(unsigned long startMFT,char*f,unsigned long long runL)
{
	unsigned int offset;
	char byte;
	int length,contentOffset;
	char*name,*flag;
	//FILE *fil=fopen(f,"w");
	unsigned long long parent;
	unsigned short int seq;
	
	
	flag=(char*)malloc(10);

while(startMFT<=runL)
{
	unsigned short int y;
	
	offset=locateIndex(startMFT,48,0);
	

	if(offset==0)
	{
		
		startMFT+=2;
		free(mbr);
		universalMFTEntry++;
		continue;
	}
	
	printf("Found File name at %li\n",offset);
	if(isValidMFT()&& offset!=0)
	{
	seq=*(unsigned short int*)(mbr+16);
	contentOffset=offset+*(unsigned short*)(mbr+offset+20);
	printf("Content Offset %i\n",contentOffset);

	byte=*(char*)(mbr+contentOffset+64);
	length=(int)byte;
			
	if(length<0)
		break;

	parent=*(unsigned long long *)(mbr+contentOffset);
	
	parent = parent & 0x0000FFFFFFFFFFFF;
	
	name=(char*)calloc((length*2),1);
	memcpy(name,(mbr+contentOffset+66),length*2);
	name=replaceZeros(name,length*2);
	name[length]='\0';
	
	printf("Name for the Entry %s\n",name);


	fputs(name,IndexF);
	fprintf(IndexF," %lu",startMFT);
	fputs("\n",IndexF);
	y=*(unsigned short int*)(mbr+22);
	if( y==3)
		strcpy(flag,"dir");
	else if ( y==1)
		strcpy(flag,"used");
	else
		strcpy(flag,"unused");

		
	printf("Special %s %lu",name,fileRefToMFTSector(parent));
	printf(" %lu",startMFT);
	printf(" %s %lu %d\n",flag,universalMFTEntry,seq);
	
	}
	universalMFTEntry++;
	startMFT+=2;

	free(mbr);
}
//fclose(fil);
/*fclose(vc);
fclose(index);
*/
}
int isValidMFT()
{
	char*sign=(char*)calloc(5,1);
	memcpy(sign,mbr,4);
	sign[5]='\0';
	if(!strncmp(sign,"FILE",4)&& strlen(sign)!=0)
	{
		printf("Valid MFT\n");
		return 1;
	}
	else
	{
		printf("Not Valid MFT\n");
		return 0;
	}

}

int isValidIndex()
{
char*sign=(char*)calloc(5,1);
	memcpy(sign,boot,4);
	sign[5]='\0';
	if(!strncmp(sign,"INDX",4)&& strlen(sign)!=0)
	{
		printf("Valid INDEX\n");
		return 1;
	}
	else
	{
		printf("Not Valid INDEX\n");
		return 0;
	}

}



unsigned long getStartMFTRef(unsigned long long  *file,signed long long *mftVCNs,unsigned long long* mftRunLength,unsigned long  startMFT)
{
int i=1;
unsigned long long cluster;
unsigned long long fileNo;
while(mftVCNs[i]!=0)
{
	
	
	printf("locating MFT %lli %llu %llu\n",mftVCNs[i-1],mftRunLength[i-1],*file);
	if(*file>mftRunLength[i-1]*(clusterSize/2))
	{
		printf("gone\n");
		*file=*file-(mftRunLength[i-1]*(clusterSize/2));
		startMFT+=mftVCNs[i]*clusterSize;
		printf("After gone startMFT = %lu and offset = %llu\n",startMFT,*file);
		
	}
	else
		return startMFT;
	i++;
}
return startMFT;
}



void scanAllMFT(signed long long *mftVCNs,unsigned long long *mftRunLength)
{
	int i=0,j=0;
	char*f=(char*)malloc(5);
	unsigned long  firstEntry;

	

		firstEntry=mftVCNs[0]*clusterSize+bootSectors[bootIndex];
		printf("First Entry %lu\n",firstEntry);
		
		while(mftVCNs[j]!=0)
		{
			itoa(j,f,10);
			scanMFT(firstEntry,f,firstEntry+mftRunLength[j]*clusterSize);
			j++;
			firstEntry+=mftVCNs[j]*clusterSize;
			
		
		}
	
	

}


unsigned long fileRefToMFTSector(unsigned long long file){

	unsigned long mftAdd=0;
	unsigned long mft;

	mftAdd=getStartMFTRef(&file,mftVCNs,mftRunLength,firstMFT);
	//mftAdd=firstMFT;
		file = file & 0x0000FFFFFFFFFFFF;
		mft=mftAdd+(unsigned long long)file*2;
return mft;
}


void lookUpMFT(unsigned long mft)
{
	unsigned long long parent;
	unsigned long sector;
	int offset=locateIndex(mft,48,0);
	offset+=*(unsigned short*)(mbr+offset+20);
	printf("Offset %d\n",offset);
	parent=*(unsigned long long *)(mbr+offset);
	sector=(fileRefToMFTSector(parent)& 0x0000FFFFFFFFFFFF);
	printf("Inuse %d\n",*(short int*)(mbr+22));
	printf("Sequence %d\n",*(short int*)(mbr+16));
	printf("Parent %lu\n",sector);
	free(mbr);

	
}


void saveLogFile(int flag)
{
	unsigned long logFileMFT;
	unsigned int startIndex;
	unsigned long long offsetToCluster=0;
	unsigned int offsetRunList;
	unsigned long long run_length,var,mft;
	unsigned  long long lastOffset=0;
	char byte,*name;
	short int length;
	int off=0;
	unsigned short int tmp=0;
	char lsnBinaryHigh[33]={'0'};
	char lsnBinaryLow[33]={'0'};
	char filler[33]={'0'};
	char formatId[21];

	logFileMFT=getMFT(bootSectors[bootIndex],bootIndex)-6;    //logFile MFT
	printf("In Save Log %lu\n",logFileMFT);
	startIndex=locateIndex(logFileMFT,128,0);
	offsetRunList=*(unsigned short int*)(mbr+startIndex+32);
	offsetToCluster = (getNextVCN(&offsetRunList,startIndex,&run_length)*clusterSize)+bootSectors[bootIndex];
	
	while(offsetToCluster!=0)
	{

		if(negativeFlag)
		{
			offsetToCluster=lastOffset-offsetToCluster;
			printf("Negative EntryIndex %llu offsetToCluster %lli\n",lastOffset,offsetToCluster);
		}
		else
		{
			offsetToCluster+=lastOffset;
			printf("Positive EntryIndex %llu offsetToCluster %lli\n",lastOffset,offsetToCluster);
		}
	
		lastOffset=offsetToCluster;
		var=0;

		while(var<run_length)
		{		
		
		printf("offsetToCluster %llu\n Last Offset %lli\n var= %llu run= %llu\n",offsetToCluster,lastOffset,var,run_length);
	

		
		get(offsetToCluster,&boot,recordSize*clusterSize*bytesSector); // 512 assumed -Default
		//printf("Char %c\n",boot[0]);
		
		if(flag)
		{
		off=0;
		while(off<recordSize*clusterSize*bytesSector)
		{
			if( *(unsigned  int*)(boot+off) == 917519 || *(unsigned  int*)(boot+off) == 983054 ||*(unsigned  int*)(boot+off) == 786445||*(unsigned  int*)(boot+off) == 851980)//||*(unsigned  int*)(boot+off) == 327686||*(unsigned  int*)(boot+off) == 393221 )
			{
				printf("Found 0F0E \n");
				
				printf("LSN %llu\n",*(unsigned long long*)(boot+off-48));
				printf("Offset %d DataLength %d %d\n",*(unsigned short int*)(boot+off+4),*(unsigned  short int*)(boot+off+6),(off+var*recordSize*clusterSize*bytesSector));
				mft=*(unsigned long long *)(boot + (*(unsigned short int*)(boot+off+4)) + off);
				
				get(fileRefToMFTSector(mft& 0x0000FFFFFFFFFFFF),&mbr,1024);
				
				if(isValidMFT())
				{
					tmp=((mft & 0xFFFF000000000000)>>48);
					printf("LogFileMFT %lu %d %0X16\n",fileRefToMFTSector(mft& 0x0000FFFFFFFFFFFF),tmp,*(unsigned long long *)(boot + (*(unsigned short int*)(boot+off+4)) + off));				
					byte=*(char*)(boot+(*(unsigned short int*)(boot+off+4)) + off +16 +64);
			    	length=(int)byte;
					
					if(length>0){

					name=(char*)calloc((length*2),1);
					memcpy(name,(boot+(*(unsigned short int*)(boot+off+4)) + off +16 +64+2),length*2);
					name=replaceZeros(name,length*2);
					name[length]='\0';
					
					printf("IndexName %s\n",name);
					printIndexMaceValues((*(unsigned short int*)(boot+off+4)) + off + 24 +64);
				
				}
				}
				free(mbr);
			}

			off+=8;
		
		
		}
		}
		else
			dumpIt(boot,recordSize*clusterSize*bytesSector);

		offsetToCluster=offsetToCluster+clusterSize;
		var++;
		}
		
		offsetToCluster=getNextVCN(&offsetRunList,startIndex,&run_length)*clusterSize;

	}
	
	

}

void getLogFile(int initialSeek)
{

	unsigned long logFileMFT;
	unsigned int bootOff=0;
	unsigned long long offsetToCluster=0;
	unsigned int offsetRunList;
	unsigned long long run_length,var,mft;
	unsigned  long long lastOffset=0;
	char byte,*name;
	short int length;
	unsigned long int y=0;
	int off=0;
	unsigned short int tmp=0;
	int endDetect=0;
	
	FILE *logfile=fopen("log.txt","rb");
	fseek(logfile,initialSeek,SEEK_SET);
		while(getFromFile(&boot,recordSize*clusterSize*bytesSector,logfile,y))// 512 assumed
		{
		//printf("Char %c\n",boot[0]);
		y+=recordSize*clusterSize*bytesSector;
		off=0;
		endDetect=0;
		while(off<recordSize*clusterSize*bytesSector)
		{
			bootOff=*(unsigned  int*)(boot+off);
			if( bootOff == 917519 || bootOff == 983054 ||bootOff == 786445||bootOff == 851980)//||*(unsigned  int*)(boot+off) == 327686||*(unsigned  int*)(boot+off) == 393221 )
			{
				printf("Found 0F0E \n");
				endDetect=0;
				printf("Offset %d DataLength %d %d\n",*(unsigned short int*)(boot+off+4),*(unsigned  short int*)(boot+off+6),off);
				mft=*(unsigned long long *)(boot + (*(unsigned short int*)(boot+off+4)) + off);
				printf("found mft sector %lu \n",fileRefToMFTSector(mft& 0x0000FFFFFFFFFFFF));
				if(!get(fileRefToMFTSector(mft& 0x0000FFFFFFFFFFFF),&mbr,1024))
				{
					off+=8;
					continue;
				}
				if(isValidMFT())
				{
					tmp=((mft & 0xFFFF000000000000)>>48);
					printf("LogFileMFT %lu %d %0X16\n",fileRefToMFTSector(mft& 0x0000FFFFFFFFFFFF),tmp,*(unsigned long long *)(boot + (*(unsigned short int*)(boot+off+4)) + off));				
					byte=*(char*)(boot+(*(unsigned short int*)(boot+off+4)) + off +16 +64);
			    	length=(int)byte;
			
					if(length>0){

					name=(char*)calloc((length*2),1);
					memcpy(name,(boot+(*(unsigned short int*)(boot+off+4)) + off +16 +64+2),length*2);
					name=replaceZeros(name,length*2);
					name[length]='\0';
					printf("IndexName %s\n",name);
					printIndexMaceValues((*(unsigned short int*)(boot+off+4)) + off + 24 +64);
				
				}
					
				}
				free(mbr);
			}
			else if(bootOff == 4294967295)
			{
				endDetect++;
			
			
			}
			else
			{
				endDetect=0;
			
			}
			

			off+=8;
		
		}
		if(endDetect>500)
				break;
		free(boot);
		}
		

}


int getFromFile(char**fileBuf,int size,FILE*logfile,int offset)
{
	
	int i=0;
	char c;
	
	*fileBuf=(char*)calloc(size,1);
	
	if(offset==0)
		printf("Inital Seek at file %d\n",ftell(logfile));
	else
		ftell(logfile);

	fflush(stdin);
	while(i<size)
	{
		c=fgetc(logfile);
		if(ferror(logfile)==0)
		{
			*(*fileBuf+i)=c;
			
			i++;

		}
		else
		{
			
			return 0;
		}

	
	}
	
	
	return 1;

}

